﻿/* Copyright (C) 2007-2010 STS Soft

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

using System;
using System.Runtime.Serialization;
using STSdb.General.Reflection;
using STSdb.Persist;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Xml;

namespace STSdb.Data
{
    //TODO: remove in C# 4
    public interface IColumnDefinition
    {
        Type PersistType { get; }
    }

    public interface IColumnDefinition<TInstance, TField> : IColumnDefinition
    {
        TField GetFieldValue(TInstance instance);
        void SetFieldValue(TInstance instance, TField value);
        //Type PersistType { get; }
    }

#if !WindowsCE && !PocketPC   
    [Serializable]
#endif
    public class DefaultColumnDefinition<TInstance, TField> : IColumnDefinition<TInstance, TField>,
#if !WindowsCE && !PocketPC   
                                                    ISerializable
#else
                                                            IXmlSerializable
#endif
    {
        protected PropertyReflector<TInstance, TField> propertyReflector;
        protected Type persistType;

        public DefaultColumnDefinition(string nestedProperty, Type persistType)
        {
            propertyReflector = new PropertyReflector<TInstance, TField>(nestedProperty);
            this.persistType = persistType;
        }

        public DefaultColumnDefinition(string nestedProperty)
            :this(nestedProperty, PersistMap.GetDefaultPersist(typeof(TField)))
        {
        }

#if !WindowsCE && !PocketPC  
        #region ISerializable Members

        protected DefaultColumnDefinition(SerializationInfo info, StreamingContext context)
        {
            persistType = (Type)info.GetValue("persist_type", typeof(Type));
            propertyReflector = new PropertyReflector<TInstance, TField>(info.GetString("property_name"));
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("persist_type", persistType);
            info.AddValue("property_name", propertyReflector.PropertyName);
        }

        #endregion
#else
        #region IXmlSerializable Members

        public XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            throw new NotImplementedException();
        }

        public void WriteXml(XmlWriter writer)
        {
            throw new NotImplementedException();
        }

        #endregion
#endif

        #region IColumnDefinition<TInstance,TField> Members

        public TField GetFieldValue(TInstance instance)
        {
            return propertyReflector.GetValue(instance);
        }

        public void SetFieldValue(TInstance instance, TField value)
        {
            propertyReflector.SetValue(instance, value);
        }

        public Type PersistType
        {
            get { return persistType; }
        }

        #endregion
    }
}
